#include "mtlib.c"
#include <string.h>
#include "Estructuras.h"
#include "LeerEscribirSector.c"

void procesarMensaje(mti_mensaje mensaje)
    {
  long sector, sectorInicial, sectorFinal, sector1, sector2, sector3, sector4, sector5;
  void * nuevosDatos = NULL;
  t_chs sectorCHS;
  int cantidad;
  char datosNulos[512];

    switch (mensaje.categoria)
        {

    case MTA_ACEPTAR: case MTA_CERRAR: return;

    case MTA_HANDSHAKE:

        mtf_enviar_handshake(centroMensajes, mensaje.remitente, 0, NULL);
        break;

    case MTA_MENSAJE:

        ;
        t_chs valorConvertidoCHS;

        switch (mensaje.tipo)
            {

        case MTE_LEER_SECTOR:

            mtf_obtener_datos(centroMensajes, mensaje.codigo, &sector);


            if(FlagLog == 1){
                    //logueo de lectura
                    archivoLogueo = fopen(pathArchivoLogueo, "a"); //abro el archivo
                    descriptorArchivo = fileno(archivoLogueo);
                    log_registrar (descriptorArchivo, nombreDelProceso, nivelDeLog, "Tipo de Pedido: Lectura");
                    log_registrar (descriptorArchivo, nombreDelProceso, nivelDeLog, "Sector: %lu", sector);
                    fclose(archivoLogueo);
            }

            //encola pedido de lectura
            //pthread_mutex_lock(&buffer_lock);
            sem_wait(&semaforo1);
            valorConvertidoCHS = convierteSectorAChs(sector);
            meterEnCola(valorConvertidoCHS.sector, NULL, 0, valorConvertidoCHS.pista, mensaje.remitente);
            //pthread_mutex_unlock(&buffer_lock);
            sem_post(&semaforo1);
            break;

        case MTE_NULL:
            mtf_enviar_mensaje(centroMensajes, mensaje.remitente, MTR_NULL);
            break;
        case MTE_ESCRIBIR_SECTOR:

            mtf_obtener_datos(centroMensajes, mensaje.codigo, &sector, (void**) &nuevosDatos);

            if(FlagLog == 1){
                    //logueo de escritura
                    archivoLogueo = fopen(pathArchivoLogueo, "a"); //abro el archivo
                    descriptorArchivo = fileno(archivoLogueo);
                    log_registrar (descriptorArchivo, nombreDelProceso, nivelDeLog, "Tipo de Pedido: Escritura");
                    log_registrar (descriptorArchivo, nombreDelProceso, nivelDeLog, "Sector: %lu", sector);
                    fclose(archivoLogueo);
            }

            //encola pedido de escritura
            //pthread_mutex_lock(&buffer_lock);
            sem_wait(&semaforo1);
            valorConvertidoCHS = convierteSectorAChs(sector);
            meterEnCola(valorConvertidoCHS.sector, (char*) nuevosDatos, 1, valorConvertidoCHS.pista, mensaje.remitente);
            //pthread_mutex_unlock(&buffer_lock);
            sem_post(&semaforo1);
            free(nuevosDatos);
            break;

        case MTE_INFO_DISCO:
            mtf_obtener_datos(centroMensajes, mensaje.codigo, &sector);
            sectorCHS = convierteSectorAChs(sector);
            mtf_enviar_mensaje(centroMensajes, mensaje.remitente,sectorCHS.pista ,sectorCHS.sector);
            break;

        case MTQ_LIMPIAR_DISCO:

            mtf_obtener_datos(centroMensajes, mensaje.codigo ,&sectorInicial, &sectorFinal);
            for(sectorInicial; sectorInicial <= sectorFinal; sectorInicial++){
            //pthread_mutex_lock(&buffer_lock2);
            sem_wait(&semaforo2);
            escribirSector(sectorInicial, datosNulos);
            //pthread_mutex_unlock(&buffer_lock2);
            sem_post(&semaforo2);
            }
            break;

        case MTE_TRACE_DISCO:

        mtf_obtener_datos(centroMensajes, mensaje.codigo , &cantidad, &sector1, &sector2, &sector3 , &sector4, &sector5);
        int i;
        t_chs sectorCHS[5];

        sectorCHS[0] = convierteSectorAChs(sector1);
        sectorCHS[1] = convierteSectorAChs(sector2);
        sectorCHS[2] = convierteSectorAChs(sector3);
        sectorCHS[3] = convierteSectorAChs(sector4);
        sectorCHS[4] = convierteSectorAChs(sector5);

        for(i = 0 ; i < 5 ; i++){
        //pthread_mutex_lock(&buffer_lock);
        sem_wait(&semaforo1);
        meterEnCola(sectorCHS[i].sector, NULL, 2, sectorCHS[i].pista, mensaje.remitente);
        //pthread_mutex_unlock(&buffer_lock);
        sem_post(&semaforo1);
        }
        break;
        default:
            mtf_enviar_mensaje(centroMensajes, mensaje.remitente,
                    MTQ_MENSAJE_NO_VALIDO);
            break;
            }
        break;
        }
    }



void procesarColaDeSectores(void)
{

    while (!pararEjecucion)
    {

        while (colaFte != 0)
        {
            t_nodo * nodoAProcesar;
            void * datosDeSector;
            int resultado;

            //pthread_mutex_lock(&buffer_lock);
            sem_wait(&semaforo1);
            nodoAProcesar = algoritmoDePlanificacion ();
            //pthread_mutex_unlock(&buffer_lock);
            sem_post(&semaforo1);

                if(nodoAProcesar -> tipo == 0){
                sleep(T_Lectura);

                if(FlagLog == 1){
                        //loguea informacion de peticion
                        archivoLogueo = fopen(pathArchivoLogueo, "a"); //abro el archivo
                        descriptorArchivo = fileno(archivoLogueo);
                        logueo(nodoAProcesar, descriptorArchivo);
                        fclose(archivoLogueo);
                }

                //leer sector
                //pthread_mutex_lock(&buffer_lock2);
                sem_wait(&semaforo2);
                datosDeSector = (void *) leerSector(nodoAProcesar -> nroSector);
                //pthread_mutex_unlock(&buffer_lock2);
                sem_post(&semaforo2);
                
                //enviar datos de lectura
                if(datosDeSector == SECTOR_INVALIDO_LECTURA) mtf_enviar_mensaje(centroMensajes, nodoAProcesar->remitente, MTR_NO_LEYO_SECTOR, nodoAProcesar->nroSector, 65);
                if (datosDeSector == FALLO_MALLOC) mtf_enviar_mensaje(centroMensajes, nodoAProcesar->remitente, MTR_NO_LEYO_SECTOR, nodoAProcesar->nroSector, 66);
                mtf_enviar_mensaje (centroMensajes, nodoAProcesar->remitente, MTR_DATOS_SECTOR, nodoAProcesar->nroSector, datosDeSector);
                }
                if(nodoAProcesar -> tipo == 1){

                    sleep(T_Escritura);

                    if(FlagLog == 1){

                            //loguea informacion de peticion
                            archivoLogueo = fopen(pathArchivoLogueo, "a"); //abro el archivo
                            descriptorArchivo = fileno(archivoLogueo);
                            logueo(nodoAProcesar, descriptorArchivo);
                            fclose(archivoLogueo);
                    }

                    //escribir sector
                    //pthread_mutex_lock(&buffer_lock2);
                    sem_wait(&semaforo2);
                    resultado = escribirSector(nodoAProcesar->nroSector,nodoAProcesar->datos);
                    //pthread_mutex_unlock(&buffer_lock2);
                    sem_post(&semaforo2);
                    //enviar datos de escritura
                    if(resultado == SECTOR_INVALIDO_ESCRITURA) mtf_enviar_mensaje(centroMensajes, nodoAProcesar->remitente, MTR_NO_ESCRIBIO_SECTOR, nodoAProcesar->nroSector, 65);
                    if(resultado == FALLO_MSYNC) mtf_enviar_mensaje(centroMensajes, nodoAProcesar->remitente, MTR_NO_ESCRIBIO_SECTOR, nodoAProcesar->nroSector, 66);
                    mtf_enviar_mensaje (centroMensajes, nodoAProcesar->remitente, MTR_ESCRIBIO_SECTOR, nodoAProcesar->nroSector);
                }

                if(nodoAProcesar -> tipo == 2){
                	trace(nodoAProcesar);
                }
         }
    }
}

